<script setup lang="ts">
import { nextTick, onMounted, ref, toRaw } from 'vue';
import PassCard from './components/PassCard.vue';
import { PASSWORD_ENUM } from '@/utils/constant';
import { getStorageItem, setStorageItem } from '@/utils/lf';
import 'vant/lib/toast/style'
import CreateAndEditPassword from './components/CreateAndEditPassword.vue';
import BScroll from '@better-scroll/core'
import ConfirmUser from '@/components/ConfirmUser.vue';
import dayjs from 'dayjs';
import { showFailToast, showSuccessToast } from 'vant';

export interface Password {
  id: string;
  title: string;
  password: string;
  account: string;
  logo: string;
}

const showExportAndImport = ref(false);
const passwordList = ref<Password[]>([])
const scrollBox = ref<HTMLDivElement>();
const confirmUser = ref<InstanceType<typeof ConfirmUser>>();
const fileInput = ref<HTMLInputElement | null>(null);
const jsonData = ref();
const createAccountRef = ref<InstanceType<typeof CreateAndEditPassword>>();
const accountScroller = ref<BScroll>()
const onAddNewPassword = () => {
  createAccountRef.value?.showCreatePopup();
}

onMounted(() => {
  updatePasswordList();
  // 初始化滚动: 不加延迟手机上无法滑动
  setTimeout(() => {
    accountScroller.value = new BScroll(scrollBox.value!, {
      click: true,
    })
  }, 100);
})

const updatePasswordList = async () => {
  passwordList.value = await getStorageItem(PASSWORD_ENUM.LIST_KEY) as Password[] || []
}

const selectToExportOrImport = () => {
  showExportAndImport.value = true;
  // exportJsonToFile(toRaw(passwordList));
}

// 使用 File System Access API 导出 JSON 文件的函数
async function exportJsonToFile(data, suggestedName = 'data.json') {
  try {
    // 检查浏览器是否支持 File System Access API
    if (!('showSaveFilePicker' in window)) {
      throw new Error('File System Access API is not supported in this browser.');
    }

    // 配置文件选择器选项
    const options = {
      suggestedName: suggestedName,
      types: [
        {
          description: 'JSON Files',
          accept: { 'application/json': ['.json'] }
        }
      ]
    };

    // 显示保存文件选择器，让用户选择保存位置和文件名
    // @ts-expect-error: 因为这是浏览器最新的 api, vscode 暂时不支持，所以这里忽略错误
    const fileHandle = await window.showSaveFilePicker(options);

    // 创建可写流
    const writable = await fileHandle.createWritable();

    // 将 JSON 数据转换为字符串并写入文件（带缩进格式化）
    await writable.write(JSON.stringify(data, null, 2));

    // 关闭流，完成保存
    await writable.close();

    console.log('JSON file saved successfully!');
  } catch (error) {
    console.error('Error saving JSON file:', error);
    // 可选：回退到传统下载方式
    fallbackDownloadJson(data, suggestedName);
  }
}

// 可选：如果 API 不支持，回退到 Blob 下载方式
function fallbackDownloadJson(data, filename) {
  const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
  console.log('Fallback: JSON file downloaded.');
}

const exportData = () => {
  if (passwordList.value.length > 0) {
    confirmUser.value?.showConfirmUserPopup();
  } else {
    showFailToast('没有数据可以导出~');
  }
}

const onUserConfirmed = (result: boolean) => {
  if (result) {
    exportJsonToFile(passwordList.value, `password-${dayjs().format('YYYY年MM月DD日 HH点mm分ss秒')}.json`)
  }
}

const importData = async () => {
  // @ts-expect-error 最新的 api
  // note: 这个方法只有在 localhost 或者 https 下才能使用
  if (window.showOpenFilePicker) {
    try {
      // @ts-expect-error 最新的 api
      const [fileHandle] = await window.showOpenFilePicker({
        types: [
          {
            description: 'JSON 文件',
            accept: { 'application/json': ['.json'] }
          }
        ],
        multiple: false
      });

      const file = await fileHandle.getFile();
      const text = await file.text();
      jsonData.value = JSON.parse(text);
      passwordList.value = jsonData.value;
      showExportAndImport.value = false;
      showSuccessToast('导入成功');
      setStorageItem(PASSWORD_ENUM.LIST_KEY, toRaw(passwordList.value));
      nextTick(() => {
        accountScroller.value?.refresh();
      })
      return;
    } catch (err) {
      // @ts-expect-error any
      if (err.name === 'AbortError') return;
      console.error('读取文件失败:', err);
    }
  } else {
    // 兼容模式：触发隐藏 input
    fileInput.value?.click();
  }

}


function handleFileInput(event: Event) {
  const target = event.target as HTMLInputElement;
  const file = target.files?.[0];
  if (!file) return;

  const reader = new FileReader();
  reader.onload = (e) => {
    try {
      jsonData.value = JSON.parse(e.target?.result as string);
    } catch (err) {
      console.error('解析 JSON 失败:', err);
    }
  };
  reader.readAsText(file);

  // 清空 input，否则无法重复选择同一文件
  target.value = '';
}


</script>

<template>
  <van-nav-bar>
    <template #title>
      <div class="flex">
        <span class="mr-2">钢铁匣</span>
        <svg @click="selectToExportOrImport" t="1754907339835" class="icon w-[22px] h-[22px]" viewBox="0 0 1024 1024"
          version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7856" width="200" height="200">
          <path
            d="M49.688261 559.761728H216.560838c23.309364 0 42.181523 18.872159 42.181523 42.125356v295.49533c0 23.309364 18.928327 42.23769 42.23769 42.23769h168.838426V12.918442L49.688261 559.761728z"
            fill="#297EFE" p-id="7857"></path>
          <path
            d="M974.311739 477.252198h-166.81641a42.181523 42.181523 0 0 1-42.23769-42.181523v-295.439162a42.23769 42.23769 0 0 0-42.23769-42.23769H554.181523v926.589327l420.130216-546.730952z"
            fill="#BAD5FF" p-id="7858"></path>
        </svg>
      </div>
    </template>
    <template #right>
      <svg @click="onAddNewPassword" t="1754907226951" class="icon w-[22px] h-[22px]" viewBox="0 0 1024 1024"
        version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3405" width="200" height="200">
        <path d="M512 512m-512 0a512 512 0 1 0 1024 0 512 512 0 1 0-1024 0Z" fill="#326FEF" p-id="3406"></path>
        <path d="M288 480m32 0l384 0q32 0 32 32l0 0q0 32-32 32l-384 0q-32 0-32-32l0 0q0-32 32-32Z" fill="#FFFFFF"
          p-id="3407"></path>
        <path d="M480 736m0-32l0-384q0-32 32-32l0 0q32 0 32 32l0 384q0 32-32 32l0 0q-32 0-32-32Z" fill="#FFFFFF"
          p-id="3408"></path>
      </svg>
    </template>
  </van-nav-bar>
  <div class="pass-box" ref="scrollBox">
    <div class="scroll-box flex flex-col gap-2">
      <PassCard v-for="(item, idx) in passwordList" :key="item.id" :cardInfo="item"
        :class="idx === 0 ? 'mt-2' : idx === passwordList.length - 1 ? 'mb-0' : ''"
        @update:passwordList="updatePasswordList" />
      <h3 class="text-center text-neutral-300 py-4">{{ passwordList.length === 0 ? '暂无数据' : '没有更多数据了' }}</h3>
    </div>
  </div>
  <CreateAndEditPassword ref="createAccountRef" mode="create" @update:passwordList="updatePasswordList" />
  <van-dialog v-model:show="showExportAndImport" title="请选择要执行的操作" show-cancel-button width="60%">
    <div class="p-4 flex flex-col gap-2">
      <van-button size="small" @click="importData">选择文件导入数据</van-button>
      <van-button size="small" @click="exportData">导出数据</van-button>
    </div>
  </van-dialog>
  <ConfirmUser ref="confirmUser" title="请输入您的密码" tip="请注意周边环境" @result="onUserConfirmed($event)" />
  <input type="file" ref="fileInput" accept=".json,application/json" style="display: none" @change="handleFileInput" />
</template>

<style lang="scss" scoped>
.pass-box {
  overflow-y: hidden;
  height: calc(100dvh - 100px);
}

:deep(.van-uploader__upload) {
  margin: 0;
}
</style>